/**
 * Copyright (c) 2024 - CARThunder
 * All Rights Reserved by Chengdu CARThunder Intelligent Technology Co., LTD and its affiliates.
 * You may not use, copy, distribute, modify, transmit in any form this file
 * except in compliance with CARThunder in writing by applicable law.
 * <p>
 * <p>
 * file description.
 *
 * @file filename
 * @brief brief function description.
 * @details detailed function description.
 * @version 1.0
 * @author author_name
 * @date last_modified_date
 * <p>
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                     NAME               DESCRIPTION
 * 2024-07-30              junjieluo         Create it.
 * <p>
 * file description.
 * @file filename
 * @brief brief function description.
 * @details detailed function description.
 * @version 1.0
 * @author author_name
 * @date last_modified_date
 * <p>
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                     NAME               DESCRIPTION
 * 2024-07-30              junjieluo         Create it.
 * <p>
 * file description.
 * @file filename
 * @brief brief function description.
 * @details detailed function description.
 * @version 1.0
 * @author author_name
 * @date last_modified_date
 * <p>
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                     NAME               DESCRIPTION
 * 2024-07-30              junjieluo         Create it.
 */

/**
 * file description.
 * @file filename
 * @brief brief function description.
 * @details detailed function description.
 * @version 1.0
 * @author author_name
 * @date last_modified_date
 *
 *      Edit History
 *      ----------------------------------------------------------------------------
 *      DATE                     NAME               DESCRIPTION
 *      2024-07-30              junjieluo         Create it.
 *
 */

package com.cart.musicdemo.base.service;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;

import android.text.TextUtils;
import android.util.Log;

import com.cart.musicdemo.MainActivity;
import com.cart.musicdemo.R;
import com.cart.musicdemo.adapter.PlayListAdapter;
import com.cart.musicdemo.base.utils.FileUtils;
import com.cart.musicdemo.base.utils.PreferencesUtil;
import com.cart.musicdemo.model.SongModel;
import com.cart.musicdemo.model.UpdateEventUI;


import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class MusicService extends Service {
    private final FileSystemManager fileSystemManager = FileSystemManager.getInstance();
    private final MusicPlayerManager musicPlayerService = MusicPlayerManager.getInstance();
    private List<SongModel> randomPlaylist = new ArrayList<>();
    private List<SongModel> playedSongs = new ArrayList<>();
    //播放列表
    private List<SongModel> songsList = new ArrayList<>();
    //专辑数据源
    private Map<String, List<SongModel>> albumClassification = new HashMap<>();
    //文件树
    private FileSystemManager.FolderNode fileTreeRootNode;
    //歌手数据源
    private Map<String, List<SongModel>> singerClassification = new HashMap<>();
    //所有歌曲列表
    private List<SongModel> allSongs = new ArrayList<>();

    //用于返回Activity实体改变播放界面UI数据
    private SongModel songModelActivity;
    /**
     * The constant MODE_SEQUENCE.
     */
    public static final int LIST = 0;
    private int currentPlayMode = 0;
    /**
     * The constant MODE_SHUFFLE.
     */
    public static final int RANDOM = 1;
    /**
     * The constant MODE_REPEAT_ONE.
     */
    public static final int LOOP = 2;
    public int mPosition = 0;
    private static final String CHANNEL_ID = "MusicServiceChannel";
    private static final int NOTIFICATION_ID = 1;
    private static final String TAG = "MusicService";
    private SongModel lastSongmodel;

    @Override
    public void onCreate() {
        super.onCreate();
        this.mPosition = mPosition;
        initData();
        createNotificationChannel();
        startForegroundService();
        memoryPlay();
    }

    private void memoryPlay() {
        String lastPath = PreferencesUtil.getPlaybackPath(this);
        if (lastPath == null) {
            // 或者其他合适的默认值
            lastPath = "";
        }
        List<SongModel> songModels = fileSystemManager.searchFiles(lastPath);
        if (songModels.size() > 0) {
            lastSongmodel = songModels.get(0);
        }
        Integer lastPosition = PreferencesUtil.getPlaybackPosition(this);
        if (lastPosition == null) {
            lastPosition = 0; // 或者其他合适的默认值
        }
        if (!TextUtils.isEmpty(lastPath)) {
            try {
                musicPlayerService.initMediaSeekOn(lastPath, lastPosition);
                if (lastSongmodel != null) {
                    if (this.callBackUpdateMemoryPlayUi != null) {
                        this.callBackUpdateMemoryPlayUi.callBackUpdateMemoryPlayUi();
                    }
                }
            } catch (RuntimeException exception) {
                SongModel defaultSong = fileSystemManager.getDefaultSong();
                play(defaultSong, true);
            }
        }
    }

    public SongModel updateAlbum() {
        if (lastSongmodel == null) {
            return new SongModel();
        }
        return lastSongmodel;
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel serviceChannel = new NotificationChannel(CHANNEL_ID,
                getString(R.string.usb_servise), NotificationManager.IMPORTANCE_DEFAULT);
            NotificationManager manager = getSystemService(NotificationManager.class);
            if (manager != null) {
                manager.createNotificationChannel(serviceChannel);
            }
        }
    }

    private void startForegroundService() {
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
            notificationIntent, 0);
        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle(getString(R.string.usb_name))
            .setContentText(getString(R.string.usb_is_playing))
            .setSmallIcon(R.drawable.ic_baseline_headset_24)
            .setContentIntent(pendingIntent).build();

        startForeground(NOTIFICATION_ID, notification);
    }

    //播放逻辑处理
    public void play(SongModel songModel, boolean isRestPlayer) {
        //播放界面展示信息获取
        songModelActivity = new SongModel();
        songModelActivity.setBitmap(FileUtils.getCoverImage(this, songModel));
        songModelActivity.setName(songModel.getName());
        songModelActivity.setSinger(songModel.getSinger());
        callBackUpdateAlbum.updateAlbum();
        if (!TextUtils.isEmpty(songModel.getPath())) {
            Log.e(TAG, String.format("当前状态：%s  是否切换歌曲：%s",
                musicPlayerService.isPlaying(), isRestPlayer));
            PreferencesUtil.savePlaybackPath(this, songModel.getPath());
            if (!isRestPlayer && musicPlayerService.isPlaying()) {
                musicPlayerService.pause();
                if (callBackPlayListAdapter != null) {
                    callBackPlayListAdapter.updatePlayListAdapter(null);
                }
                EventBus.getDefault().post(new UpdateEventUI("Test"));
            } else {
                musicPlayerService.play(songModel);
                for (int i = 0; i < songsList.size(); i++) {
                    songsList.get(i).setPlaying(mPosition == i);
                }
                songsList.get(mPosition).setPlaying(true);
                if (callBackPlayListAdapter != null) {
                    callBackPlayListAdapter.updatePlayListAdapter(null);
                }
                EventBus.getDefault().post(new UpdateEventUI("Test"));
            }
        } else {
            toastPathInvalid.pathInvalid();
        }
    }

    public void listAndLoopLast() {
        mPosition--;
        if (mPosition < 0) {
            mPosition = songsList.size() - 1;
        }
        play(songsList.get(mPosition), true);
    }

    public void last() {
        switch (currentPlayMode) {
            case LIST:
                listAndLoopLast();
                break;
            case RANDOM:
                if (playedSongs.size() > 1) {
                    // 播放倒数第二首歌曲
                    SongModel lastSong = playedSongs.get(playedSongs.size() - 2);
                    play(lastSong, true);
                    // 移除最后播放的歌曲
                    playedSongs.remove(playedSongs.size() - 1);
                } else if (playedSongs.size() == 1) {
                    // 如果仅有一首歌曲被播放过，则继续播放当前歌曲
                    SongModel currentSong = playedSongs.get(0);
                    play(currentSong, true);
                }
                break;
            case LOOP:
                listAndLoopLast();
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + currentPlayMode);
        }
    }

    public void next() {
        mPosition++;
        if (mPosition >= songsList.size()) {
            mPosition = 0;
        }
        play(songsList.get(mPosition), true);
    }

    public void order() {
        if (currentPlayMode == 2) {
            currentPlayMode = 0;
        } else {
            currentPlayMode = currentPlayMode + 1;
        }
    }

    public void playRandom() {
        /**
         * 如果randomPlaylist为空，代码将遍历名为songsList的列表，这个列表可能包含了所有的歌曲。
         * 然后，除了当前正在播放的歌曲（由变量mPosition指示）之外，
         * 其他所有歌曲都被添加到randomPlaylist中。
         */
        if (randomPlaylist.isEmpty()) {
            for (int i = 0; i < songsList.size(); i++) {
                if (i != mPosition) {
                    randomPlaylist.add(songsList.get(i));
                }
            }
        }

        if (!randomPlaylist.isEmpty()) {
            Random random = new Random();
            int index = random.nextInt(randomPlaylist.size());
            SongModel nextSong = randomPlaylist.get(index);
            try {
                for (int i = 0; i < songsList.size(); i++) {
                    String path = "";
                    // 检查 path 是否为空
                    if (songsList.get(i) != null
                        && songsList.get(i).getPath() != null
                        && nextSong.getPath() != null) {
                        path = songsList.get(i).getPath();
                        if (path != "" && path.equals(nextSong.getPath())) {
                            mPosition = i;
                        }
                    }
                }
            } catch (RuntimeException exception) {
                Log.e(TAG, "" + exception);
            }
            play(nextSong, true);

            randomPlaylist.remove(index);
            playedSongs.add(nextSong);

            if (playedSongs.size() == songsList.size()) {
                playedSongs.clear();
            }
        }
    }

    public void nextMusic() {
        switch (currentPlayMode) {
            case LIST:
                next();
                break;
            case RANDOM:
                playRandom();
                break;
            case LOOP:
                next();
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + currentPlayMode);
        }
    }

    public void completeNextMusic() {
        switch (currentPlayMode) {
            case LIST:
                next();
                break;
            case RANDOM:
                playRandom();
                break;
            case LOOP:
                play(songsList.get(mPosition), true);
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + currentPlayMode);
        }
    }

    public void initData() {
        List<SongModel> musicData = fileSystemManager.getSongModelFlattened();
        allSongs = fileSystemManager.getSongModelFlattened();
        singerClassification = fileSystemManager.getSingerClassification();
        albumClassification = fileSystemManager.getAlbumClassification();
        fileTreeRootNode = fileSystemManager.getRootNode();
        // nodeMap是用来搜索搜索节点做的缓存，rootNode才被用来渲染文件夹
        FileSystemManager.FolderNode rootNode = fileSystemManager.getRootNode();
        if (!musicData.isEmpty()) {
            songsList.addAll(musicData);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopForeground(true);
        musicPlayerService.destroy();
    }

    /**
     * 更新播放列表歌曲.
     * @param list music list
     */
    public void updateSongList(List<SongModel> list) {
        if (list != null && callBackPlayListAdapter != null) {
            this.songsList = list;
        }
        callBackPlayListAdapter.updatePlayListAdapter(list);
    }

    /**
     * 更新播放列表UI.
     */
    public void updatePlayListUI() {
        if (callBackPlayListAdapter != null) {
            callBackPlayListAdapter.updatePlayListAdapter(null);
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new MusicBinder();
    }

    public int getCurrentPlayMode() {
        return currentPlayMode;
    }

    //回调接口
    public static interface CallBackUpdateAdapter {
        void updateAdapter();
    }

    public static interface CallBackPathInvalid {
        void pathInvalid();
    }

    public static interface CallBackUpdateAlbum {
        void updateAlbum();
    }

    public static interface CallBackUpdateMemoryPlayUi {
        void callBackUpdateMemoryPlayUi();
    }

    //用于PlayListFragment与Service的回调
    public static interface CallBackPlayListAdapter {
        void updatePlayListAdapter(List<SongModel> songModels);
    }

    //用于SongFragment与Service的回调
    public static interface CallBackSongListAdater {
        void updatePlayListAdapter();
    }


    //private CallBackUpdateAdapter adapter;
    private CallBackPathInvalid toastPathInvalid;
    private CallBackUpdateAlbum callBackUpdateAlbum;
    private CallBackPlayListAdapter callBackPlayListAdapter;
    private CallBackUpdateMemoryPlayUi callBackUpdateMemoryPlayUi;

    public class MusicBinder extends Binder {
        public void play(int position, Boolean reset) {
            MusicService.this.play(songsList.get(position), reset);
            songsList.get(position).setPlaying(true);
        }

        public int getPosition() {
            return MusicService.this.mPosition;
        }

        public void setCurrentPosition(int maPosition) {
            MusicService.this.mPosition = maPosition;
        }

        public void last() {
            MusicService.this.last();
        }

        public int getCurrentPlayMode() {
            return MusicService.this.getCurrentPlayMode();
        }

        public void nextMusic() {
            MusicService.this.nextMusic();
        }

        public void completeNextMusic() {
            MusicService.this.completeNextMusic();
        }

        public void order() {
            MusicService.this.order();
        }

        /**
         * 播放列表默认全部歌曲.
         * @return music list
         */
        public List<SongModel> getSonglist() {
            return MusicService.this.songsList != null
                ? MusicService.this.songsList : new ArrayList<>();
        }

        /**
         * 获取所有歌曲.
         * @return music list
         */
        public List<SongModel> getAllSongs() {
            return MusicService.this.allSongs != null
                ? MusicService.this.allSongs : new ArrayList<>();
        }

        public FileSystemManager.FolderNode getFileTreeRootNode() {
            return fileTreeRootNode != null
                ? fileTreeRootNode :
                new FileSystemManager.FolderNode("", "");
        }

        public Map<String, List<SongModel>> getSingerlist() {
            return MusicService.this.singerClassification != null
                ? MusicService.this.singerClassification : new HashMap<>();
        }

        public Map<String, List<SongModel>> getAlbumlist() {
            return MusicService.this.albumClassification != null
                ? MusicService.this.albumClassification : new HashMap<>();
        }

        public int currentPlayMode() {
            return MusicService.this.currentPlayMode;
        }

        public void setPlayListAdapter(CallBackPlayListAdapter adapter) {
            MusicService.this.callBackPlayListAdapter = adapter;
        }

        public void updateMemoryPlayUi(CallBackUpdateMemoryPlayUi callBackUpdateMemoryPlayUi) {
            MusicService.this.callBackUpdateMemoryPlayUi = callBackUpdateMemoryPlayUi;
        }

        public void toastPathInvalid(CallBackPathInvalid toastPathInvalid) {
            MusicService.this.toastPathInvalid = toastPathInvalid;
        }

        public void updateAlbumImage(CallBackUpdateAlbum callBackUpdateAlbum) {
            MusicService.this.callBackUpdateAlbum = callBackUpdateAlbum;
        }

        public SongModel getSongModel() {
            return songModelActivity;
        }

        //获取到以后用来更新ui
        public SongModel getUpdateSongModel() {
            return MusicService.this.updateAlbum();
        }

        public void updateSongList(List<SongModel> list) {
            MusicService.this.updateSongList(list);
        }

        //更新播放列表UI
        public void updatePlayListUI() {
            MusicService.this.updatePlayListUI();
        }
    }
}